﻿// 王猛昭.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#if 1
//oop实现动态栈
class Stack
{
public:
    Stack(int size = 10)
    {
        this->stack_ = new int[size] {};
        this->top_ = 0;
        this->capaity_ = size;
    }
    ~Stack()
    {
        delete[]this->stack_;
        this->stack_ = nullptr;
    }
    //栈的左值拷贝构造函数
    Stack(const Stack& str)
    {
        std::cout << this << std::endl;
        std::cout << "SeqStack(const SeqStack& src)" <<std:: endl;
        // this -> s2   src & s1
        // this->stack_ = src.stack_;  浅拷贝
        // 按照src占用的堆内存的大小重新给当前s2开辟自己的堆内存
        // 再把堆上的数据拷贝过来，让s2自己的stack_指针指向新的
        // 堆内存
        this->stack_ = new int[str.capaity_];
        for (int i = 0; i < str.top_; i++)
        {
            this->stack_[i] = str.stack_[i];
        }

        this->capaity_ = str.capaity_;
        this->top_ = str.top_;
    }

    
    //栈的右值拷贝构造函数
    Stack(Stack&& str)
    {
        this->stack_ = str.stack_;
        this->capaity_ = str.capaity_;
        this->top_ = str.top_;
        str.stack_ = nullptr;
    }

    // 左值赋值函数  把当前对象 *this继续返回
    Stack& operator=(const Stack& src)
    {
        std::cout << "operator=" <<std::endl;
        // 防止自赋值
        if (this == &src)
            return *this;

        // this->s1    src->s1
        delete[]this->stack_; // 释放原来占用的堆内存

        this->stack_ = new int[src.capaity_];
        for (int i = 0; i < src.top_; i++)
        {
            this->stack_[i] = src.stack_[i];
        }

        this->capaity_ = src.capaity_;
        this->top_ = src.top_;
        return *this;
    }
    //栈的右值赋值函数
    Stack& operator=(Stack&& str)
    {
        delete[]this->stack_;
        this->capaity_ = str.capaity_;
        this->top_ = str.top_;
        str.stack_ = nullptr;
        return *this;
    }
public:
    void Push(int val)
    {
        if (this->Full())
        {
            Expand(2 * this->capaity_);
        }
        this->stack_[this->top_] = val;
        this->top_++;
    }
    void Pop()
    {
        if (this->Empty())
            return;
        this->top_--;
    }
    int Get()
    {
        return this->stack_[this->top_ - 1];
    }
    bool Empty() { return this->top_ == 0; }
    bool Full() { return this->top_ == this->capaity_; }
private:
    void Expand(int size)
    {
        int* p = new int[size] {};
        memcpy(p, this->stack_, sizeof(int) * this->capaity_);
        delete[]this->stack_;
        this->stack_ = p;
        this->capaity_ = size;
    }
private:
    int* stack_;
    int capaity_;//栈的容量
    int top_;
};

int main()
{
    Stack s(5);
    s.Push(10);
    s.Push(20);
    s.Push(30);
    s.Push(40);
    s.Push(50);
    s.Push(60);
    s.Push(70);
    while (!s.Empty())
    {
        std::cout << s.Get() << " ";
        s.Pop();
    }
    std::cout << std::endl;
}
#endif
#if 0
class String
{
public:
    // str参数接收的就是外部传进来的字符串   String str;
    String(const char* str = nullptr)
    {
        if (str != nullptr)
        {
            // new开辟内存失败不是返回空指针，而是抛异常，此处省略处理
            this->m_data = new char[strlen(str) + 1];
            strcpy(this->m_data, str);
        }
        else
        {
            //this->m_data = NULL;
            this->m_data = new char('\0');
        }
    }
    ~String()
    {
        delete[]this->m_data;
        this->m_data = nullptr;
    }
    String(const String& str) // str m_data
    {
        this->m_data = new char[strlen(str.m_data) + 1];
        strcpy(this->m_data, str.m_data);
    }
    String& operator=(const String& str) // str m_data
    {
        // 防止自赋值
        if (this == &str)
            return *this;

        delete[]this->m_data;

        this->m_data = new char[strlen(str.m_data) + 1];
        strcpy(this->m_data, str.m_data);
        return *this;
    }
    //带右值引用的赋值函数
    String& operator=(String&& str)
    {
        
        delete[]this->m_data;
        this->m_data = str.m_data;
        str.m_data = nullptr;
        return *this;
    }

    char* Str() { return m_data; }
private:
    char* m_data;
};
String GetString(String str)
{
    char* s = str.Str();
    String newStr(s);   // String(const char *str)
    return newStr;
}
int main()
{
    String str1("hello world");
    String str2;

    str2 = GetString(str1);  // main上用newStr创建出来一个新的临时对象
    std::cout << str2.Str() <<std::endl;

    /*String str1("hello");  // 普通构造函数
    String str2 = str1; // 拷贝构造函数
    String str3(str2);  // 拷贝构造函数
    str3 = str1;*/      // 赋值函数
}





//oop实现动态环形队列
class Que
{
public:
    Que(int size = 10)
    {
        std::cout << this << std::endl;
        std::cout << "Que(int)" << std::endl;
        this->que_ = new int[size] {};
        this->front_ = 0;
        this->rear_ = 0;
        this->num_ = size;
    }
    //拷贝构造函数（深拷贝）
    Que(const Que& src)
    {
        std::cout << this << std::endl;
        std::cout << "Que(Que&src)" << std::endl;
        this->que_ = new int[src.num_];
        int i = 0, j = src.front_;

        for ( ; j != src.rear_; i++, j = (j + 1) % src.num_)
        {
            this->que_[i] = src.que_[j];
        }
        this->front_ = 0;
        this->num_ = src.num_;
        this->rear_ = i;
    }
    //赋值操作函数
    Que& operator=(Que& src)
    {   
        if (this == &src)
            return *this;
        delete[]this->que_;
        this->que_ = new int[src.num_];
         

        for (int j = src.front_; j != src.rear_;  j = (j + 1) % src.num_)
        {
            this->que_[j] = src.que_[j];
        }
        this->front_ = src.front_;
        this->num_ = src.num_;
        this->rear_ = src.rear_;
        return *this;
    }
    Que(Que&& src)
    {
        cout << " Que(Que&& src)" << endl;
        this->que = src.que;
        this->num_ = src.num_;
        this->front_ = src.front_;
        this->rear_ = src.rear_;

        src.que = nullptr;
    }
    Que& operator=(Que&& src)
    {
        cout << "右值赋值函数" << endl;
        delete[]this->que; // 释放原来占用的堆内存
        this->que = src.que; //重指向

        src.que = nullptr;
        this->num_ = src.num_;
        this->front_ = src.front_;
        this->rear_ = src.rear_;
        return *this;
    }
    ~Que()
    {
        std::cout << this << std::endl;
        std::cout << "~Que" << std::endl;
        delete[]this->que_;
        this->que_ = nullptr;
    }
    void Push(int val)
    {
        if (this->Full())
        {
            this->Expand(this->num_ * 2);
        }
        this->que_[this->rear_] = val;
        this->rear_ = (this->rear_ + 1) % this->num_;
    }
    void Pop()
    {
        if (this->Empty())
            return;
        this->front_ = (this->front_ + 1) % this->num_;
    }
    int Get()
    {
        return this->que_[this->front_];
    }
    bool Empty() { return this->rear_ == this->front_; }
    bool Full() { return this->front_ == (this->rear_ + 1) % this->num_; }
private:
    void Expand(int size)
    {
        int* p = new int[size] {};
        int i = 0;
        int j = this->front_;
        for (; j != this->rear_; i++, j = (j + 1) % this->num_)
        {
            p[i] = this->que_[j];
        }
        delete[]this->que_;
        this->que_ = p;
        this->front_ = 0;
        this->rear_ = i;
        this->num_ = size;
    }
private:
    int* que_;
    int front_;
    int rear_;
    int num_;
};
int main()
{
    Que q(5);
    Que s = q;
    q.Push(10);
    q.Push(20);
    q.Push(30);
    q.Push(40);
    q.Push(50);
    q.Push(60);
    q.Push(70);
    while (!q.Empty())
    {
        std::cout << q.Get() << " ";
        q.Pop();
    }
    std::cout << std::endl;
}
#endif

# if 0
//oop实现单链表
class Link
{
public:
    Link()
    {
        this->head_ = new Node;
        
    }
    ~Link()
    {

        while (this->head_ != nullptr)
        {
            Node* p = this->head_->next;
            delete this->head_;
            this->head_ = p;

        }

    }
    Link(Link& src)
    {
        cout << " Link(Link& src)" << endl;

        this->head_ = new Node;
        Node* q = this->head_;
        Node* p = src.head_;

        while (p->next != nullptr)
        {
            q->next = new Node;
            q->next->data = p->next->data;
            q = q->next;
            p = p->next;
        }
        q = nullptr;
    }

    Link(Link&& src)
    {

        this->head_ = new Node;
        this->head_->next = src.head_->next;
        delete src.head_;
    }

    //左值
    Link& operator=(Link& src)
    {
        cout << "左值赋值函数" << endl;
        // 防止自赋值
        if (this == &src)
        {
            return *this;
        }

        Node* p = this->head_->next;
        Node* q = src.head_->next;
        while (p != nullptr && q != nullptr)
        {
            p->data = q->data;
            p = p->next;
            q = q->next;
        }
        if (p == nullptr && q != nullptr)
        {

            while (q != nullptr)
            {
                p = new Node;
                p->data = q->data;
                p = p->next;
                q = q->next;
            }
            p = nullptr;
        }
        if (q == nullptr && p != nullptr)
        {
            Node* p1 = p->next;
            p = nullptr;
            while (p1 != nullptr)
            {
                Node* p2 = p1->next;
                delete p1;
                p1 = p2;
            }
        }
        return *this;
    }

    // 右值引用
    Link& operator=(Link&& src)
    {
        Node* p = this->head_->next;
        Node* q = this->head_->next->next;
        while (p != nullptr)
        {
            delete p;
            p = q;
            q = q->next;
        }
        this->head_ = src.head_->next;
        delete src.head_;
        return *this;
    }
public:
    void InsertHead(int val) // 头插法
    {
        Node* p = new Node(val, this->head_->next);
        
        this->head_->next = p;
    }
    void InsertTail(int val)// 尾插法
    {
        Node* p = this->head_;

        while (p->next != nullptr)
        {
            p = p->next;
        }
        Node* p1 = new Node(val);
        
        p->next = p1;
        
    }
    void Remove(int val)     // 删除所有值为val的节点
    {
        Node* p = this->head_->next;
        Node* q = this->head_;
        while (p != nullptr)
        {
            if (p->data == val)
            {
                q->next = p->next;
                delete p;
                p = q->next;
            }
            else
            {
                q = p;
                p = p->next;
            }
        }
    }
    void Show()              // 打印链表内容
    {
        Node* p = this->head_->next;
        while (p != nullptr)
        {
            std::cout << p->data << " ";
            p = p->next;
        }
        std::cout << std::endl;
    }
private:
    struct Node
    {
        
        int data;
        Node* next;
        Node(int a = 0, Node* p = nullptr)
        {
            this->data = a;
            this->next = p;
        }
    };

    Node* head_; // 指向链表头节点的指针
};
int main()
{
    Link link;

    link.InsertTail(10);
    link.InsertTail(20);
    link.InsertTail(30);
    link.Show();
    link.InsertHead(10);
    link.InsertHead(20);
    link.InsertHead(30);
    link.Show();
    link.Remove(30);
    link.Show();
}

#endif

